/**********************************
 * INIT
 **********************************/
var currentLinks = getLinkUndirectedHrefs(); // current links on the page, useful to detect document changes that change links

setTimeout("updateTagsFromLocalStorage()", 2000);

var menuCleared = true;

/**********************************
 * EVENTS
 **********************************/

// context menus updating on mouseover to relax on the mousedown
document.addEventListener("mouseover", function(event) {
    var el = event.target;
    var valid = false;
    while (el != undefined && !valid) {
        if (el.tagName.toLowerCase() == "a") {
            valid = true;
        } else {
            el = el.parent;
        }
    }
    if (valid) {
        var url = null;
        if (el.href != undefined && el.href != null) {
            url = getDirectUrl(el.href);
        }
        /// Sends [cmd, linkUrl] to background page
        chrome.extension.sendRequest({
            cmd:"updateContextMenu",
            linkUrl: url
        }, function(response) {
            menuCleared = false;
        });
    }
}, true); // event bubbling to fire the handler on the smallest child

// clear the context menus on mouseout, to prevent it to display on pages which doesn't allow the extension to work
document.addEventListener("mouseout", function(event) {
    if (!menuCleared) {
        chrome.extension.sendRequest({
            cmd:"clearMenu"
        }, function(response) {
            menuCleared = true;
        });
    }
});

// on document change, update tags if links are changed
document.addEventListener("change", function(event) {
    var changedDocumentLinks = getLinkUndirectedHrefs();
    if (changedDocumentLinks.length > currentLinks.length) {
        updateTagsFromLocalStorage();
        currentLinks = getLinkUndirectedHrefs();
    }
    else {
        var i=0;
        var newLinks = false;
        var sz = changedDocumentLinks.length;
        while (i<sz && !newLinks) {
            if (changedDocumentLinks[i] != currentLinks[i]) {
               newLinks = true;
            }
            i++;
        }
        if (newLinks) {
            updateTagsFromLocalStorage();
            currentLinks = getLinkHrefs();
        }
    }
});

// listener for incoming messages (background page and popup)
chrome.extension.onRequest.addListener(function(request, sender, sendResponse) {
    switch (request.cmd) {
        /// Receives [cmd] from background page
        case "updateTags":
            updateTagsFromLocalStorage();
            sendResponse({}); // notify
            break;
            
        /// Receives [cmd, redirectUrl] from popup
        case "redirectToUrl":
            location.href = request.redirectUrl;
            break;
    }
});

/**********************************
 * METHODS
 **********************************/

// update tags with a request to the background page
function updateTagsFromLocalStorage() {
    /// Sends [cmd, data] to background page
    /// Receives [links, color] from background page
    var links = getLinkUndirectedHrefs().join(",");
    chrome.extension.sendRequest({
        cmd:"getTaggedLinks",
        data:links
    }, function(response) {
            // links is null if no links need to be tagged
            if (response.links != null) {
                var aTags = document.getElementsByTagName("a");
                var taggedLinks = response.links.split(",");
                var taggedColors = response.colors.split(",");
                var i=0;
                var j=0;
                var aTagsSz = aTags.length;
                var taggedLinksSz = taggedLinks.length;
                while (i<aTagsSz && j<taggedLinksSz) {
                    if (aTags[i].href != undefined && aTags[i].href != null && getDirectUrl(aTags[i].href) == taggedLinks[j]) {
                        aTags[i].style.color = taggedColors[j];
                        j++;
                    }
                    i++;
                }
            }
    });
}

/**********************************
 * UTILS
 **********************************/
// return links hrefs in current page without redirecting patterns
function getLinkUndirectedHrefs() {
    var aTags = document.getElementsByTagName("a");
    var arr = [];
    var sz = aTags.length;
    for (var i=0; i<sz; i++) {
        if (aTags[i].href != undefined && aTags[i].href != null) {
            arr.push(getDirectUrl(aTags[i].href));
        }
    }
    return arr;
}

// prevent tagging some popular redirecting patterns or messed up urls that will change everytime
function getDirectUrl(url) {
    var directUrl = url;
    // popular redirecting pattern
    if (url != undefined && url.indexOf("=http") > -1) {
        try {
            directUrl = "http"+unescape(url.split("=http")[1].split("&")[0]);
        } catch (e) {
            console.log("failed to convert url "+url);
        }
    }
    // specific to google results page numbers
    else if (url.indexOf("google.") > -1 && url.indexOf("ei=") > -1) {
        var left = url.split("ei=")[0];
        var right = url.substring(left.length).split("&")[1];
        directUrl = left + right;
    }
    return directUrl;
}
